﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;

namespace ApiFileTest.Controllers
{
    
    public class HomeController : ApiController
    {
        private const string MimeType = "application/octet-stream";
        /// <summary>
        /// 直接下载
        /// </summary>
        /// <param name="filename"></param>
        /// <returns></returns>
        [HttpGet]
        public HttpResponseMessage DownLoad(string filename)
        {
            var fullFilPath = Path.Combine(@"E:\Code\ValueProviderTest\ApiFileTest\download", filename);
            if (!File.Exists(fullFilPath))
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }
            FileStream fileStream = File.Open(fullFilPath,FileMode.Open,FileAccess.Read,FileShare.ReadWrite);
            var response = new HttpResponseMessage();
            response.Content = new StreamContent(fileStream);
            response.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment") { FileName=filename};
            response.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(MimeType);
            response.Content.Headers.ContentLength = fileStream.Length;
            return response;
        }
        /// <summary>
        /// 断点续传
        /// </summary>
        /// <param name="filename"></param>
        /// <returns></returns>
        [HttpGet]
        public HttpResponseMessage DownLoadHttp(string filename)
        {
            var fullFilPath = Path.Combine(@"E:\Code\ValueProviderTest\ApiFileTest\download", filename);
            if (!File.Exists(fullFilPath))
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }
            if (Request.Headers.Range == null || Request.Headers.Range.Ranges.Count == 0 || Request.Headers.Range.Ranges.FirstOrDefault().From.Value == 0)
            {
                var stream = File.Open(fullFilPath, FileMode.Open, FileAccess.Read, FileShare.Read);
                var response = new HttpResponseMessage(HttpStatusCode.OK);
                response.Content = new StreamContent(stream);
                response.Headers.AcceptRanges.Add("bytes");
                response.Content.Headers.ContentLength = stream.Length;
                response.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(MimeType);
                response.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment") { FileName = filename };
                return response;
            }
            else
            {
                var item = Request.Headers.Range.Ranges.FirstOrDefault();
                if (item != null && item.From.HasValue)
                {
                    var response = this.GetPartialContent(filename,item.From.Value);
                   
                }
                return new HttpResponseMessage(HttpStatusCode.OK);
            }
        }
        private HttpResponseMessage GetPartialContent(string filename, long partial)
        {
            var response = new HttpResponseMessage();
            var fullFilPath = Path.Combine(@"E:\Code\ValueProviderTest\ApiFileTest\download", filename);
            if (!File.Exists(fullFilPath))
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }
            FileInfo info = new FileInfo(fullFilPath);
            long startByte = partial;
            var memoryStream = new MemoryStream();
            var buffer = new byte[65536];
            using (var filstream = File.Open(fullFilPath, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                
                filstream.Seek(startByte,SeekOrigin.Begin);
                int length = Convert.ToInt32((info.Length-1)-startByte)+1;
                var bytesRead = filstream.Read(buffer, 0, Math.Min(length, buffer.Length));
                while (length > 0 && bytesRead > 0)
                {
                    memoryStream.Write(buffer,0,bytesRead);
                    length -= bytesRead;
                    bytesRead = filstream.Read(buffer, 0, Math.Min(length, buffer.Length));
                }
                response.Content = new StreamContent(memoryStream);
            }
            response.Headers.AcceptRanges.Add("bytes");
            response.StatusCode = HttpStatusCode.PartialContent;
            response.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue(MimeType);
            response.Content.Headers.ContentLength = File.Open(fullFilPath,FileMode.Open,FileAccess.Read,FileShare.Read).Length;
            response.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment") { FileName=filename};
            return response;
        }
    }
}
